\documentclass[a4paper,spanish] {article} 
\usepackage [spanish] {babel} 
\usepackage [latin1]{inputenc}
\usepackage{graphicx}
\usepackage{caratula}
\usepackage{subfig}
\usepackage{dsfont}
\usepackage{algorithm}
\usepackage{amsmath}
\usepackage{algorithmic}
\usepackage{sidecap}
\usepackage{slashbox}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\pagestyle{empty}

\newcommand{\real}{\ensuremath{\mathbb{R}}}


\parindent = 0 pt
\parskip = 11 pt

\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\pagestyle{empty}

%links
\usepackage{hyperref}
\hypersetup{
    colorlinks,%
    citecolor=blue,%
    filecolor=blue,%
    linkcolor=blue,%
    urlcolor=blue
}


\addtolength{\oddsidemargin}{-1in}
\addtolength{\textwidth}{2in}


\begin{document}
\pagestyle{headings}



\newpage

\materia{Sistemas Operativos}
\submateria{Primer Cuatrimestre del 2013}
\titulo{Scheduling de Tareas }

\integrante{Gonzalo Fuentes Bahamondes}{412/10}{ness00@gmail.com}
\integrante{Helen Lizana}{118/08}{hsle.22@gmail.com}
\integrante{Gabriel Astorgano}{467/10}{astorsk81991@hotmail.com}

\maketitle


\newpage
\tableofcontents
\newpage

\newpage

\section{Introducci\'on }

Este trabajo pr\'actico se enfoca en el an\'alisis de las interacciones de procesos y los distintos tipos de Schedulers, como FIFO, Round Robin, RSDL y otros.
El scheduler es un componente funcional muy importante de los sistemas operativos multitarea y multiproceso, y es esencial en los sistemas operativos de tiempo real.
Su funci\'on consiste en repartir el tiempo disponible de un microprocesador entre todos los procesos 
que est\'an disponibles para su ejecuci\'on.Si se utiliza bien este concepto,
se logra la ilusi\'on de que se est\'an ejecutando en simult\'aneo varias tareas. 
Recordemos que el procesador, solo puede ejecutar una instrucci\'on por vez.

A la hora de implementar un scheduler se tienen en cuenta diferentes pol\'iticas:
\begin{itemize}
   \item Ecuanimidad (fairness): que cada proceso reciba una dosis ''justa'' de CPU (para alguna definici\'on de justicia).  
   \item Eficiencia: tratar de que la CPU est\'e ocupada todo el tiempo.  
   \item Carga del sistema: minimizar la cant. de procesos listos que est\'en esperando CPU. 
   \item Tiempo de respuesta: minimizar el tiempo de respuesta percibido por los usuarios interactivos.
   \item Latencia: minimizar el tiempo requerido para que un proceso empiece a dar resultados.
   \item Tiempo ejecuci\'on: minimizar el tiempo total que le toma a un proceso ejecutar 	completamente.
   \item Rendimiento (throughput): maximizar el n\'umero de procesos terminados por unidad de tiempo. 
   \item Liberaci\'on de recursos: hacer que terminen cuanto antes los procesos que tiene reservados m\'as recursos. 
\end{itemize}
Dichas politicas son contradictorias entre si, lo cual lleva a realizar una combinacion de algunas de estas para
mejorar el rendimiento. Debido a estas politicas no se puede decir cual ser\'ia el mejor scheduler.

\section{Ejercicio 1}

Para el ejercicio 1, se nos pide desarrollar un nuevo tipo de tarea \emph{TaskConsola}. El mismo simula una tarea que interact\'ua con la consola, generando un bloqueo en el CPU de duraci\'on
aleatoria un numero predeterminado de veces. Para esto utilizamos el siguiente c\'odigo:

\begin {verbatim}
void TaskConsola(int pid, vector<int> params) { 
	int n = params[0];
    int bmin = params[1];
    int bmax = params[2];
    int modulo = bmax - bmin +1;
    for(int i = 0; i < n; i++) {
	    	uso_IO(pid, rand() % modulo + bmin);
		
    }
}
\end{verbatim}

La tarea TaskConsola recibe la id del proceso actual as\'i como 3 par\'ametros enteros: n, que es el n\'umero de llamadas bloqueantes a realizar, y bmin y bmax, que son los rangos de la duraci\'on aleatoria de dichas llamadas bloqueantes. El c\'odigo llama a la funcion \emph{$uso\_IO$} con la id del proceso actual y un valor aleatorio para la duraci\'on de la misma. La tarea no simula ning\'un uso adicional del CPU para enfatizar el bloqueo de cpu por las llamadas de entrada/salida.

Probando el siguiente lote:

\begin {verbatim}
TaskConsola 10 1 10
\end{verbatim}

Que solo ejecuta diez de estas tareas con una duraci\'on entre 1 y 10 ciclos, obtenemos el siguiente resultado con un scheduler FCFS:

{\bfseries TestTaskConsola ej1lote.tsk:}
\\
\includegraphics[width=150mm]{ej1.png}

\section{Ejercicio 2}

En este ejercicio se pide escribir un lote de tareas para probar el algoritmo de scheduling FCFS. Utilizamos una tarea que consume 100 ciclos de CPU, asi como 2 tareas TaskConsola que no consumen el CPU, pero que s\'i lo bloquean con llamadas de entrada/salida de duraci\'on aleatoria. Si bien no sabemos cuanto tiempo durar\'an las llamadas bloqueantes, invocamos un total de 7 llamadas de una duraci\'on cercana a 10 ciclos para ocupar alrededor de 70 ciclos y comparar estas dos tareas con la que consume el CPU.

El lote utilizado es el siguiente:

\begin {verbatim}
TaskCPU 50
TaskConsola 3 1 10
TaskConsola 5 4 30
\end{verbatim}


Implementamos un algoritmo de scheduling First Come First Served (FCFS) seg\'un la clase basesched.h. Internamente solo es una estructura de cola generada utilizando la estructura \emph{queue} de la standard library de C++. Esta estructura modela el comportamiento de un scheduler FCFS, ya que los elementos se agregan, obtienen y eliminan seg\'un el orden en que fueron llegando. Al agregar una tarea con el m\'etodo \emph{load}, llamamos al m\'etodo \emph{push}, que la agrega al final de la queue. Al ocurrir un tick, ya sea porque la tarea sigue ejecut\'andose o porque haya generado una llamada bloqueante, el scheduler informa que la tarea siguiente sigue siendo la primera en la queue (o la tarea IDLE, en caso de que no haya m\'as tareas), ya que el algoritmo FCFS nos dice que la primer tarea sigue ejecut\'andose hasta que termine. Si la tarea est\'a bloqueada, el m\'etodo \emph{unblock} no realiza ninguna operaci\'on porque la primer tarea a\'un no ha finalizado. Una vez finalizada una tarea, se pide la 
siguiente tarea y luego se la elimina de la queue, porque el scheduler seguir\'a informando que \'esta es la tarea actual hasta que termine.

Para este algoritmo, una de nuestras hip\'otesis es que por un lado, el CPU tiene una alta eficiencia al ejecutar tareas que hagan un amplio uso del CPU porque \'estas se ejecutan sin ser interrumpidas por otras tareas. Por otro lado, dicha eficiencia se pierde con tareas que ejecuten bloqueos largos y numerosos, porque el CPU no puede cambiar que tarea est\'a ejecutando y se genera \emph{busy waiting}. Una vez que se ejecuta un proceso interactivo se tiene una alta latencia y tiempo de respuesta, y el tiempo de ejecuci\'on es \'optimo. El rendimiento depende en su mayor parte del orden en que llegan los procesos al scheduler, porque como la prioridad se da por el orden de llegada, puede ocurrir que se genere inanici\'on solo por la cronolog\'ia de los procesos.

Realizamos una simulaci\'on de este scheduler con el lote \emph{ej2lote.tsk}, variando la cantidad de cores entre 1 y 3.

{\bfseries Ej2lote.tsk con 1 core:}
\\
\includegraphics[width=150mm]{ej21core.png}

{\bfseries Ej2lote.tsk con 2 cores:}
\\
\includegraphics[width=150mm]{ej22core.png}

{\bfseries Ej2lote.tsk con 3 cores:}
\\
\includegraphics[width=150mm]{ej23core.png}

Luego de correr los tests, se puede apreciar que una vez que la tarea 1 tiene control de un
procesador, su eficiencia es \'optima porque no es interrumpido por las tareas 0 o 2. 
Sin embargo, esta apropiaci\'on del procesador evita que se pueda paralelizar la ejecuci\'on de
tareas sin agregar m\'as procesadores. Al aumentar la cantidad de procesadores se logra una
paralelizaci\'on total una vez que se tiene tantos procesadores como tareas. Incluso en el 
caso de 2 procesadores, la tarea 0 bloquea al procesador con llamadas de entrada/salida y no 
se puede aprovechar este tiempo muerto para ejecutar parte de la tarea 2. A pesar de la 
paralelizaci\'on, se dedican cores adicionales a cubrir tareas de poco uso de CPU, como en 
el caso de 3 cores en el que 2 procesadores pasan la mayor parte del tiempo bloqueados. Debido al
orden en que se cargan las tareas en este experimento, si no se tienen suficientes cores la tarea
1 no se ejecutara hasta que la tarea 0 termine, y ya que la tarea 1 es la \'unica que realmente 
hace un uso amplio del CPU, se pierde rendimiento al no poder agilizar procesos mientras otros 
est\'an bloqueados. Gr\'aficamente, se nota el volumen de \emph{busy waiting} generado por las
llamadas de entrada/salida al comparar los 80-100 ciclos perdidos esperando desbloqueos mientras 
que la tarea 1 utiliza al CPU intensivamente por 100 ciclos, desperdiciando casi el mismo tiempo 
en esperas que en ejecuciones de procesos efectivamente.

\newpage

\section{Ejercicio 3}


Para la implementaci\'on del Scheduler Round-Robin, utilizamos un entero que representa el quantum global y fijo que van a obtener todas las tareas al comenzar su turno; un vector de enteros, del largo de la cantidad de procesadores de la computadora, el cual contiene el quantum actual que tiene cada CPU para su tarea ejecutando.

Para obtener el comportamiento de una lista circular en tiempo de ejecuci\'on, utilizamos una cola donde guardamos los pid para ver qui\'en es el pr\'oximo proceso a ejecutar.

\noindent int quantum;\\
int std::vector<int> quantumporcpu;\\
std::queue<int> tareas;\\

En sched\_rr.cpp procedimos a la implementaci\'on de los m\'etodos de la siguiente manera:\\
\begin{itemize}
\item \textbf{load} se encarga de encolar el pid de la nueva tarea en la cola de procesos (con un push a tareas) cuando esta se carga en el sistema.

\item \textbf{tick}  Si el motivo por el cual fue llamada esta funci\'on fue por la constante TICK, entonces aumentamos el quantum que puede ejecutar la tarea en su CPU correspondiente, si esta llegase a valer el cuantum fijo que tenemos entonces reseteamos el quantum de este CPU al valor 0, luego colocamos a la tarea actual del CPU al principio de la cola de tareas con un push y ponemos a ejecutar la pr\'oxima tarea que haya en la cola.
En los casos que la tarea ejecuto un BLOCK o un EXIT, restauramos el quantum actual del CPU al quantum global y sacamos esta tarea de la cola.
Por \'ultimo, si ya no hay tareas en la cola, ponemos a ejecutar la tarea IDLE.

\item \textbf{unblock} Cuando esta funci\'on se ejecuta, un proceso se desbloquea, por lo cual agregamos al mismo a la cola de tareas.
\end{itemize}


\newpage
\section{Ejercicio 4}



\input{Ejercicio4.txt}

\section{Ejercicio 5}

\input{Ejercicio5.txt}
\section{Ejercicio 6}

En este ejercicio nos piden programar la tarea tipo \textbf{TaskBatch} que recibe dos par\'ametros:  total de CPU $(total\_cpu)$ y cantidad de bloqueos $(cant\_blocks)$. Esta tarea debe realizar $cant\_blocks$ llamadas bloqueantes, en momentos elegidos pseudoaleatoriamente. Cada llamada bloqueante debe durar un $(1)$ ciclo de reloj. 
\\El tiempo de CPU total que utilice una tarea TaskBatch ser\'a el $total\_cpu$ ciclos de reloj (incluyendo el tiempo utilizado para a lanzar las llamadas bloqueantes, no as\'i el tiempo en que la tarea permanezca bloqueada)

Para esto creamos un vector booleano: ''bloqueos'', que contendr\'a en cada posicion \textbf{true} si se puede ejecutar dicho ciclo o \textbf{false} en caso contrario, cada posicion del vector se llena de forma aleatoria respetando la cantidad de bloqueos que se paso como parametro. Luego en otro ciclo se ejecuta el uso del cpu dependiendo del valor que contenga el vector ''bloqueos'' en cada iteracion.

\begin{verbatim}

function TaskBatch( total_cpu, cant_bloqueos)
  vector bloqueos
  int temp;
  for i=0 hasta blocks
      temp = rand()%total_cpu;
      while(timeBlocks[temp])
           temp = rand()%total_cpu;
      end while
      timeBlocks[temp] = true;
  end for

  for i de total_cpu
    if bloqueos(i)
      bloquear cpu
    else
      usar cpu
    end if
  end for
end function

\end{verbatim}


\section{Ejercicio 7}

En este ejercicio nos piden evaluar dos m\'etricas para ver el rendimiento del scheduler de Round\- Robin
con respecto a un lote de procesos con llamadas bloqueantes aleatorias. Para esto se dise\~namos 
un lote de tareas TaskBatch $(Ej7lote.tsk)$ con un tiempo de ejecuci\'on de 30 ciclos de reloj
por cada una de ellas con sus respectivas cantidades de bloqueos, dejando fijo en un ciclo de 
reloj el costo de cambio de contexto y dos ciclos el de migraci\'on. \\
El lote consiste en 5 tareas, elegimos esta cantidad para que se pudiera mostrar
de ver facilmente los tiempos de ejecuci\'on, se muestra a continuaci\'on:

\begin{center}

TaskBatch 30  4 \\
TaskBatch 30  8 \\
TaskBatch 30 15 \\
TaskBatch 30  3 \\
TaskBatch 30 20 \\
\end{center}

Las m\'etricas que decidimos analizar son: Response Time \footnote{Es el intervalo de tiempo desde que 
un proceso es cargado hasta que brinda su primer respuesta} y el Turnaround \footnote{Es el intervalo de tiempo desde que 
un proceso es cargado hasta que este finaliza su ejecuci\'on} promedios para evaluar cual de los quatums elegidos es el m\'as ''\'optimo''.

Los experimentos consistiran en la variaci\'on de quantum y en la cantidad de procesadores. Para 
determinar un valor adecuado para el quantum, tuvimos en cuenta el hecho que no podemos saber 
de antemano cuando ocurrir\'an las llamadas de E/S. La variaci\'on de la cantidad de cores que usamos fue 
para reflejar el trabajo que realizan los procesadores con 1, 2 y 4 cores, \'estos dos ultimos son
los m\'as comunes en los procesadores actuales. A su vez, la elecci\'on de los quantums 
fue tomado con respecto al tiempo promedio de ''Uso de CPU'' de los procesos a ejecutar. En el caso
de nuestro lote el tiempo promedio de uso de CPU es de 30 ciclos de reloj, por lo tanto quisimos ver
como se comportaban el scheqduler con un quatum chico, mediano y grande con respecto a este valor 
\footnote{Decimos grande si el valor es mas cercano al tiempo de uso de CPU}, por lo tanto elegimos
 los quatums: 5, 10 y 20.

\subsection{M\'etrica: Response Time}

Para esta m\'etrica realizaremos varias corridas del lote dejando fijo la misma cantidad de cores 
y quantum de forma tal que se pueda reflejar el tiempo de repuesta promedio ($TR_{prom}$)y ver como es el comportamiento 
del scheduler con respecto a los procesos con llamadas bloqueates aleatorias. 

 $$TR_{prom}= \frac{\sum_{i=1}^{n}(TF_i - TI_i)}{n}$$ 
\\Donde TF\_i es el tiempo que finaliza el proceso i,  TI\_i es el tiempo de llegada al scheduler
 del proceso i y n la cantidad de procesos.

En las siguientes imagenes se podr\'a ver la aletoriedad de la llamadas bloqueantes, y como var\'ia su ejecuci\'on
respecto al aumento de quantum esperando ver que el tiempo de respuesta disminuya.
\newpage

\subsubsection{Primer Caso: Un core}


\underline{\bfseries 1 core y 5 quatum:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{m1_1core5qR1.png}
\\
\textbf{2do ejec.}
\\
\includegraphics[width=150mm]{m1_1core5qR2.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{m1_1core5qR3.png}


\underline{\bfseries 1 core y 10 quatum:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{m1_1core10qR1.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{m1_1core10qR2.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{m1_1core10qR3.png}

\underline{\bfseries 1 core y 20 quatum:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{m1_1core20qR1.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{m1_1core20qR2.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{m1_1core20qR3.png}

Ve\'amos la siguiente tabla  que muestra el tiempo de respuesta promedio (en cliclos
de reloj) de las corridas realizadas separando los casos con los quatums utilizados:

\begin{table}[!hbt]
\begin{center}
   \begin{tabular}{| c | c | c | c | }
	 
	 \hline
	\backslashbox{Nro Ejec}{Quantum}  & 5 & 10 & 20 \\ \hline
     1ra & 180.5 & 158.2 & 158.6 \\ \hline
     2da & 186.8 & 164.6 & 156.6 \\ \hline
     3ra & 182.4 & 160.2 & 151.0 \\ 
    \hline
   \end{tabular}
   
\caption{Tiempo de Respuesta Promedio - 1 core}
 \end{center}
 
\end{table}

Podemos observar que si bien varia un poco los tiempos entre cada corrida de los casos, esta diferencia
no supera los 10 ciclos de reloj, y que a medida que aumentamos el quantum, el tiempo de respuesta mejora.
Si comparamos la mejora de pasar del quantum $5$ al $10$ este es del $13\%$ y si pasamos del quantum $5$
al $20$ la mejora es a penas del $6\%$. En el segundo caso, la mejora menor a lo esperado al 
suponer que al tener mayor quantum el Tiempo de Espera podr\'ia mejorar. Tambi\'en podemos ver que el 
tiempo de ejecuci\'on total de los procesos apenas mejora en 10 ciclos de reloj entre cada variaci\'on 
de quantum, para el quatum $5$ el tiempo es de $230$, cuando el quatum es de $10$ el tiempo total 
es de $220$ al igual que cuando el quatum es de $20$.


\subsubsection{Segundo Caso: Dos Cores}

Suponemos que al haber mayor cantidad de cores el tiempo de respuesta mejorar\'a aun m\'as.

\underline{\bfseries 2 core y 5 quatum:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{m1_2core5qR1.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{m1_2core5qR2.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{m1_2core5qR3.png}



\underline{\bfseries 2 core y 10 quatum:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{m1_2core10qR1.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{m1_2core10qR2.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{m1_2core10qR3.png}



\underline{\bfseries 2 core y 20 quatum:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{m1_2core20qR1.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{m1_2core20qR2.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{m1_2core20qR3.png}


Veamos en la siguiente tabla de los Tiempos de Respuesta promedio (en ciclos
de reloj) de las corridas realizadas con respecto al aumento del quatum:
 \begin{table}[!hbt]
\begin{center}
   \begin{tabular}{| c | c | c | c | }
	 
	 \hline
	\backslashbox{Nro Ejec}{Quantum}  & 5 & 10 & 20 \\ \hline
     1ra & 114.0 & 105.8 &  92.2 \\ \hline
     2da & 116.8 & 104.8 & 103.4 \\ \hline
     3ra & 129.6 & 105.4 & 100.8 \\ 
    \hline
   \end{tabular}
   \caption{Tiempo de Respuesta Promedio - 2 cores}
 \end{center}
 \end{table}
Al igual que el caso anterior la variaci\'on del tiempo promedio entre corridas es m\'inima y
el tiempo de mejora entre el aumento de quantums tampoco es muy significativa, ya que
de pasar de $5$ a $10$ quantum la mejora es del $7\%$, y al pasar de $10$ a $20$ quantum es del $12\%$.
En este caso los porcentajes de mejora entre uno y otro es mucho menor con respecto al
primer experimento. Si comparamos este cuadro con el primero se puede ver que el tiempo de 
respuesta mejor\'o en un $38\%$, debido a que, al haber otro CPU, el trabajo se 
comparte en ambos y el tiempo de respuesta mejora.

\subsubsection{Tercer Caso: Cuatro Cores}

\underline{\bfseries 4 cores y 5 quatum:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{m1_4core5qR1.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{m1_4core5qR2.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{m1_4core5qR3.png}


\underline{\bfseries 4 cores y 10 quatum:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{m1_4core10qR1.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{m1_4core10qR2.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{m1_4core10qR3.png}


\underline{\bfseries 4 cores y 20 quatum:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{m1_4core20qR1.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{m1_4core20qR2.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{m1_4core20qR3.png}

Para este caso el waiting time es de:
Veamos en la siguiente tabla de los tiempos de respuesta promedios (en cliclos
de reloj) de las corridas realizadas
esperando ver una mejora con respecto al aumento del quantum:
 \begin{table}[!hbt]
\begin{center}
   \begin{tabular}{| c | c | c | c | }
	 
	 \hline
	\backslashbox{Nro Ejec}{Quantum}  & 5 & 10 & 20 \\ \hline
     1ra & 79.6 & 71.2 & 69.4 \\ \hline
     2da & 76.0 & 69.2 & 70.0 \\ \hline
     3ra & 78.0 & 70.4 & 69.8 \\ 
    \hline
   \end{tabular}
   \caption{Tiempo de Respuesta Promedio - 4 cores}
 \end{center}
 \end{table}

En este experimento podemos ver que los Tiempos de Respuesta entre las distintas corridas
son muy similares. Esto se debe a la presencia de m\'as procesadores que hacen que el tiempo de espera a que haya un CPU disponible sea mucho menor.
El tiempo de respuesta promedio mejora muy poco en cuanto al aumento del quantum. Se puede observar adem\'as
 que al terminar las tareas con menos llamadas bloqueantes, algunos CPU quedan ''ociosos''. Por otro lado,
 se aprecia que mejora mucho el Tiempo de Respuesta del lote con respecto a los otros 
 experimentos; si comparamos el primer experimento con este \'ultimo vemos que el tiempo de respuesta 
 promedio se redujo en un $54\%$.
 
Conclusiones:
\begin{description}
  \item[] \hfill \\
  El tiempo de respuesta mejora en presencia de mas cpus, a pesar de tener tareas con llamadas bloqueantes aleatorias.
  \item[] \hfill \\
  La ejecuci\'on de un lote con tareas batchs bajo las mismas condiciones de cpu y quantum var\'ia muy poco. Esto es porque
  se respeta el quantum del squeduler o en todo caso es interrumpido por alguna llamada bloqueante es por eso
  que no habia mucha mejora en cuanto al incremento del quantum.
  \item[] \hfill \\
  Para el primer experimento, si bien con el $quatum \ = \ 20$ el tiempo de respuesta es menor con respecto a los otros
  el scheduler no apovecha demasiado ese valor por la presencia de las llamadas bloqueantes,
   que interrumpen de forma inesperada haciendo que no se utilice plenamente el quantum asignado. Por lo tanto el quantum \'optimo para este caso es el quatum $10$.
  \item[] \hfill \\
  Para el segundo experimento, vemos que el tiempo de respues mejora con el aumento de cpus pero que 
  el aumento de quantum no influye demasiado por las misma razones explicadas anteriormente. En base a lo visto a las
  distintas ejecuciones del lote quantum \'optimo para este caso es  $10$.
  \item[] \hfill \\
  Para el tercer experimento, se puede concluir que a mayor precencia de cpus disponibles
  para cantidad de procesos los tiempos de respuesta dependen de estos y no del quantum. 
  Viendo el cuadro de los tiempos de promedios, el quatum \'optimos es $10$.
  
  \item[] \hfill \\
  Finalmente el quantum \'optimo para esta m\'etrica es de $quatum \ = \ 10$
  

\end{description}



\subsection{M\'etrica: Turnaround}

Al igual que el antes, realizaremos varias corridas por cada caso y calcularemos el Turnaround
 promedio ($TR_{prom}$) para ver como es el comportamiento 
del scheduler con respecto a los procesos con llamadas bloqueates aleatorias. 

 $$TR_{prom}= \frac{\sum_{i=1}^{n}(TF_i - TE_i - TI_i)}{n}$$ 
\\Donde TF\_i es el tiempo que finaliza el proceso i, TE\_i es el tiempo de ejecuci\'on, TI\_i es el 
tiempo de llegada al scheduler del proceso $i$ y $n$ la cantidad de procesos.

En los siguientes experimentos utilizaremos mismo valores de quantums y cantidad de cpus.
%un solo core
\subsection{Caso 1: Un core y distintos quatums}

Este caso lo que plantea es ver como es el comportamiento del scheduler con una cantidad relativamente 
peque\~na de cores en comparaci\'on a la cantidad de procesos, y ver como influye en el turnaround.

\underline{\bfseries 1 core y 5 quatum:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{m2_1core5qR1.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{m2_1core5qR2.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{m2_1core5qR3.png}

\underline{\bfseries 1 core y 10 quatum:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{m2_1core10qR1.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{m2_1core10qR2.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{m2_1core10qR3.png}


\underline{\bfseries 1 core y 20 quatum:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{m2_1core20qR1.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{m2_1core20qR2.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{m2_1core20qR3.png}

Se puede ver que relativamente el tiempo total de ejecuci\'on varia muy poco, entre $200$ y $220$ 
ciclos de reloj y que las tareas terminan de ejecutarse en el mismo orden, primero terminan 
aquellas que tienen pocas llamadas bloqueantes: la Tarea $0$ y $3$, y luego, las tareas $1$, $2$, $4$. 
A la vez, este orden se respetan en los $3$ casos dado que tienen la misma cantidad de llamadas 
bloqueantes en cada uno los experimentos. A continuaci\'on mostramos una tabla comparativa de los 
turnaround promedios con respecto a los diferentes quatums: 

 \begin{table}[!hbt]
\begin{center}
   \begin{tabular}{| c | c | c | c | }
	 
	 \hline
	\backslashbox{Nro Ejec}{Quantum}  & 5 & 10 & 20 \\ \hline
     1ra & 149.0 & 127.0 & 122.4 \\ \hline
     2da & 144.6 & 136.2 & 122.0 \\ \hline
     3ra & 146.0 & 130.8 & 120.2 \\ 
    \hline
   \end{tabular}
   \caption{Turnaround - 1 cores}
 \end{center}
 \end{table}

A diferencia del tiempo de respuesta, en esta m\'etrica se puede ver una m\'inima variaci\'on
con respecto a las distintas corridas del lote. Tambien se puede ver que el Turnaround promedio mejora
en un $14\%$ entre pasar del quatum $5$ al $10$ y un $8\%$ en el cambio de quatum de $10$ al $20$,
Esperabamos un porcentaje mayor sobre la mejora pero podemos ver que el tiempo promedio no
supera el $20\%$ como si se vi\'o en la otra m\'etrica.


\subsection{Caso 2: Distintos core y quatums fijos} 
% varios cores
Para este caso lo que plateamos es ver como cambian el tiempo total de ejecuci\'on, teniendo un quantum fijo y variando la cantidad de cores. 
Como primer experimento elegimos $10$ de quantum y $3$ variaciones de cores.

\underline{\bfseries 1 core:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{m2_1core10qR1.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{m2_1core10qR2.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{m2_1core10qR3.png}

\underline{\bfseries 2 cores:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{m2_2core10qR1.png}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{m2_2core10qR2.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{m2_2core10qR3.png}

\underline{\bfseries 4 cores:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{m2_4core10qR1.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{m2_4core10qR2.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{m2_4core10qR3.png}


Podemos apreciar que el turnaround mejora a medida que la cantidad de cores aumenta.

\begin{center}
   \begin{tabular}{| c | c | c |c|}
     \hline
     \backslashbox{Nro Ejec}{Cant. Cores} & 1 core & 2 cores & 4 cores\\ \hline
     1ra & 127.0 & 83.4 & 40.0\\ \hline
     2da & 136.2 & 78.8 & 41.8\\ \hline
     3ra & 130.8 & 72.2 & 38.2\\ 
     \hline
   \end{tabular}
 \end{center}

La mejora de $1$ a $2$ cores es del $34\%$ , de $2$ a $4$ cores es del $52\%$ y por \'ultimo 
de $1$ a $4$ cores es del $68,50\%$ . En cuanto al orden de las tareas, \'estas se mantienen, 
al igual que en el Caso $1$, pero se puede ver una gran mejora en los tiempos de respuesta. A
continuaci\'on un tabla que indica el $turnaround$ de las tareas por cores.
 \begin{table}[!hbt]
\begin{center}
   \begin{tabular}{| c | c | c | c | }
     \hline
     \backslashbox{Tarea}{Cant. Cores} & 1 & 2 & 4 \\ \hline
     0 &  82.0 &  47.0 & 14.0 \\ \hline
     3 &  72.0 &  62.0 & 16.0 \\ \hline
     1 & 128.0 &  76.0 & 35.0 \\ \hline
     2 & 167.0 &  62.0 & 62.0 \\ \hline
     4 & 186.0 & 124.0 & 73.0 \\ 
     \hline
   \end{tabular}
   \caption{Turnaround de tareas - 1era Ejec. - quatum 10}
 \end{center}
 \end{table}
 
  \begin{table}[!hbt]
\begin{center}
   \begin{tabular}{| c | c | c | c | }
     \hline
     \backslashbox{Tarea}{Cant. Cores} & 1 & 2 & 4 \\ \hline
     0 &  96.0 &  54.0 & 23.0 \\ \hline
     3 & 104.0 &  46.0 & 26.0 \\ \hline
     1 & 128.0 &  70.0 & 34.0 \\ \hline
     2 & 167.0 & 102.0 & 55.0 \\ \hline
     4 & 187.0 & 122.0 & 71.0 \\ 
     \hline
   \end{tabular}
      \caption{Turnaround de tareas - 2era Ejec. - quatum 10}
 \end{center}
 \end{table}
 
  \begin{table}[!hbt]
\begin{center}
   \begin{tabular}{| c | c | c | c | }
     \hline
     \backslashbox{Tarea}{Cant. Cores} & 1 & 2 & 4 \\ \hline
     0 &  88.0 &  47.0 & 22.0 \\ \hline
     3 & 168.0 &  45.0 & 18.0 \\ \hline
     1 & 130.0 &  65.0 & 32.0 \\ \hline
     2 &  83.0 &  92.0 & 52.0 \\ \hline
     4 & 185.0 & 114.0 & 67.0 \\ 
     \hline
   \end{tabular}
   \caption{Turnaround de tareas - 3era Ejec. - quatum 10}
 \end{center}
 \end{table}
 
La disponibilidad de m\'as cores aumenta el tiempo de respuesta para cuando una tarea se desbloquea. 
Es por este motivo que las tareas tardan menos en ejercutarse a pesar de mantener el mismo n\'umero 
de llamadas bloqueantes, generando as\'i un menor tiempo de ejecuci\'on del lote.

Trantando de reflejar este mismo comportamiento, probamos si mejoran los tiempos teniendo un 
mayor quantum. Para este caso aumentamos el quatum a $20$ ciclos de reloj y mantemos la misma 
variaci\'on de cores.

\underline{\bfseries 1 core:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{m2_1core20qR1.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{m2_1core20qR2.png}
\\
\textbf{3r ejec.}
\\
\includegraphics[width=150mm]{m2_1core20qR3.png}
\\
\underline{\bfseries 2 cores:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{m2_2core20qR1.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{m2_2core20qR2.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{m2_2core20qR3.png}
\\
\underline{\bfseries 4 cores:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{m2_4core20qR1.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{m2_4core20qR2.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{m2_4core20qR3.png}
\\
Podemos ver que el tiempo total de ejecuci\'on no varia con respecto al experimento anterior $(quatum 10)$, si bien cada tarea mejora su tiempo de ejecuci\'on, esta variaci\'on es m\'inima dado que a pesar de tener mayor quatum las tareas bloqueantes impiden que se utilice en su totalidad por lo tanto no que da m\'as que esperar a que \'estas se desbloqueen. En la siguiente tabla vemos los tiempos de ejecuci\'on de cada tarea:

 \begin{table}[!hbt]
\begin{center}
   \begin{tabular}{| c | c | c | c | }
     \hline
     \backslashbox{Tarea}{Cant. Cores} & 1 & 2 & 4 \\ \hline
     0 &  79.0 &  39.0 &  9.0 \\ \hline
     3 &  64.0 &  30.0 & 15.0 \\ \hline
     1 & 119.0 &  43.0 & 30.0 \\ \hline
     2 & 163.0 &  86.0 & 55.0 \\ \hline
     4 & 182.0 & 110.0 & 72.0 \\ 
     \hline
   \end{tabular}
   \caption{Turnaround de tareas - 1era Ejec. - quatum 20}
 \end{center}
 \end{table}
 
  \begin{table}[!hbt]
\begin{center}
   \begin{tabular}{| c | c | c | c | }
     \hline
     \backslashbox{Tarea}{Cant. Cores} & 1 & 2 & 4 \\ \hline
     0 &  79.0 &  33.0 & 12.0 \\ \hline
     3 &  62.0 &  24.0 & 28.0 \\ \hline
     1 & 118.0 &  65.0 & 35.0 \\ \hline
     2 & 162.0 &  92.0 & 58.0 \\ \hline
     4 & 179.0 & 110.0 & 73.0 \\ 
     \hline
   \end{tabular}
      \caption{Turnaround de tareas - 2era Ejec. - quatum 20}
 \end{center}
 \end{table}
 
  \begin{table}[!hbt]
\begin{center}
   \begin{tabular}{| c | c | c | c | }
     \hline
     \backslashbox{Tarea}{Cant. Cores} & 1 & 2 & 4 \\ \hline
     0 &  9.0 &  12.0 & 12.0 \\ \hline
     3 & 15.0 &   0.0 &  0.0 \\ \hline
     1 & 30.0 &  35.0 & 32.0 \\ \hline
     2 & 55.0 &  58.0 & 58.0 \\ \hline
     4 & 72.0 &  73.0 & 76.0 \\ 
     \hline
   \end{tabular}
   \caption{Turnaround de tareas - 3era Ejec. - quatum 20}
 \end{center}
 \end{table}

El tiempo de ejecuci\'on de cada tarea mejor\'o en apenas $5$ ciclos de reloj 
en comparaci\'on al experimento anterior (con quatum 10). Por lo tanto aumentar 
el quantum no ayuda a mejorar el rendimiento en presencia de tareas que realizan 
muchas llamadas bloqueantes.
En resumen:

\begin{description}
	
  \item[] \hfill \\
   Con los  experimentos pudimos notar que, si bien mejora el turnaround con el aumento del quantum, esta
   variaci\'on es un porcentaje muy bajo del tiempo total. Esto tambien se debe a que las tareas tienen numerosas llamadas bloqueantes
   que no permiten el aprovechar la totalidad del quatum.
  \item[] \hfill \\
   En donde si notamos mejoras significativas fue con el cambio de la cantidade de cpus, donde se puede ver claramente
   en las tablas comparativas como mejora el turnaround de cada tarea.
  \item[Caso 1:] \hfill \\
  Si se posee ''pocos'' cores para una cantidad grande de tareas, lo que ayuda a mejorar los 
  tiempos de ejecuci\'on es el aumento de quantum. En nuestro experimento, el valor \'optimo para 
  este caso es el quantum $20$.
  \item[Caso 2:] \hfill \\
  Vimos que al tener una mayor cantidad de cores para ejecutar mejora los tiempos, 
  pero que el aumento de quatum no influye demasiado dado que las tareas con llamadas bloqueantes 
  no dejan aprovecharlo. En base a lo visto, el quantum \'optimo para este caso es  $10$.
  
\end{description}


El quatum \'optimo varia en los casos de prueba dado que esta sujeto a las distintas instancias 
planteadas anteriormente, pero tendemos a decir que el quantum 10 es el \'optimo dado que
como vimos el uso de tareas con llamadas bloqueantes no permite aprovecha un quatum grande.
Esto nos lleva a concluir que el mejor quatum se podr\'a deducir luego 
de un analisis del comportamiento de los procesos y de los rescursos que se posea $(cores)$.


\section{Ejercicio 8}

Para el nuevo algoritmo de scheduling Round Robin $2$, partimos del scheduler SchedRR que dise\~namos previamente. Nos valemos de dos estructuras adicionales:

\begin{itemize}
\item \textbf{tareasporcpu:} Dado un pid de una tarea, este vector de int devuelve en que cpu se est\'a ejecutando esa tarea para controlar que no se ejecute en otro procesador.

\item \textbf{cpuportareas:} Dado un cpu, devuelve cuantas tareas se est\'an ejecutando en ese cpu, para distribuir las tareas al cpu con menor carga.

\end{itemize}

La implementaci\'on es similar, excepto por controles adicionales para que se cumpla la prohibici\'on de migraci\'on de procesos entre n\'ucleos. La cola de tareas esta vez es un vector de colas de tareas, donde cada coordenada del vector es un CPU y su cola son las tareas que solo ese CPU es capaz de ejecutar. Al cargar una tarea, buscamos que CPU tiene la menor cantidad de tareas (en \textbf{cpuportareas:}) y la misma es asignada a la cola de tareas de ese CPU. Cuando el scheduler encuentra un CPU que quiere ejecutar una tarea, se pide la primer tarea de su cola exclusiva. Si una tarea deja el scheduler y luego regresa debido a un bloqueo o porque expir\'o su quantum, buscamos a que CPU correspond\'ia (\textbf{cpuportareas:}) y la agregamos a la cola exclusiva de ese CPU para que no migre entre n\'ucleos.

Se nos pide repetir el experimento anterior, en el que analizamos las m\'etricas de Response Time y Turnaround Time del algolritmo Round Robin con esta nueva implementaci\'on que no permite migraciones. Dado que la \'unica diferencia entre los algoritmos es la prohibici\'on a los procesos de ejecutarse en un n\'ucleo diferente, solo repetiremos los experimentos con multiples cores.
\newpage
\subsection{M\'etrica: Response Time}

\subsubsection{Segundo Caso: Dos Cores}

Nuevamente, suponemos que al haber mayor cantidad de cores el tiempo de respuesta mejorar\'a con respecto a una ejecuci\'on con un core de cualquiera de ambos algoritmos. Sin embargo, puede que la prohibici\'on de cambiar de cores no permita aprovechar plenamente el aumento de cores.

\underline{\bfseries 2 core y 5 quatum:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{rr12core5quantum1.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{rr12core5quantum2.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{rr12core5quantum3.png}



\underline{\bfseries 2 core y 10 quatum:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{rr12core10quantum1.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{rr12core10quantum2.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{rr12core10quantum3.png}



\underline{\bfseries 2 core y 20 quatum:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{rr12core20quantum1.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{rr12core20quantum2.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{rr12core20quantum3.png}


Veamos en la siguiente tabla de los tiempos de respuesta promedios (en cliclos
de reloj) de las corridas realizadas:
 \begin{table}[!hbt]
\begin{center}
   \begin{tabular}{| c | c | c | c | }
	 
	 \hline
	\backslashbox{Nro Ejec}{Quantum}  & 5 & 10 & 20 \\ \hline
     1ra & 100 & 88.6 &  89.0 \\ \hline
     2da & 100.8 & 93.8 & 92.2 \\ \hline
     3ra & 98.6 & 91.2 & 90.6 \\ 
    \hline
   \end{tabular}
   \caption{Tiempo de Respuesta Promedio - 2 cores}
 \end{center}
 \end{table}

Nuevamente, notamos una amplia mejor\'ia con respecto a una ejecuci\'on con un solo core, reduciendo el tiempo de respuesta en m\'as del 50\%. Se nota, adem\'as, una peque\~na pero significativa reducci\'on del tiempo de respuesta en comparaci\'on con el scheduler de Round Robin que s\'i permite migraciones, de aproximadamente el 10\%. Esto se debe a que la prohibici\'on a las migraciones evita que se pierdan ciclos migrando el proceso. Si bien los procesos deben esperar a que su procesador correspondiente se libere, los numerosos bloqueos permiten un frecuente desalojo de procesos, por lo que el procesador propio puede liberarse r\'apidamente. 

Una vez m\'as, aumentar el quantum genera una reducci\'on del Tiempo de Respuesta, pero la diferencia es m\'inima. De hecho, mientras m\'as aumenta el quantum del scheduler que prohibe migraciones, m\'as se aproxima a su contraparte en Tiempo de Respuesta. Esto ocurre debido a que asignar m\'as quantum a una tarea les otorga el CPU por una mayor cantidad de tiempo, mientras que otras tareas pueden estar esperando a ese CPU en particular, sin poder migrar a otro. De esta forma, se desaprovecha la ventaja de prohibir migraciones para mitigar el costo de migrar entre nucleos como consecuencia de la elecci\'on del quantum.

\subsubsection{Tercer Caso: Cuatro Cores}

\underline{\bfseries 4 cores y 5 quatum:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{rr14core5q.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{rr14core5qcopy1.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{rr14core5qcopy2.png}


\underline{\bfseries 4 cores y 10 quatum:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{rr14core10q.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{rr14core10qcopy1.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{rr14core10qcopy2.png}


\underline{\bfseries 4 cores y 20 quatum:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{rr14core20q.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{rr14core20qcopy1.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{rr14core20qcopy2.png}

Veamos en la siguiente tabla de los tiempos de respuesta promedios (en ciclos
de reloj) de las corridas realizadas:


 \begin{table}[!hbt]
\begin{center}
   \begin{tabular}{| c | c | c | c | }
	 
	 \hline
	\backslashbox{Nro Ejec}{Quantum}  & 5 & 10 & 20 \\ \hline
     1ra & 61.8 & 60.2 & 59.2 \\ \hline
     2da & 61.4 & 62.2 & 59.4 \\ \hline
     3ra & 61.2 & 60.8 & 59.6 \\ 
    \hline
   \end{tabular}
   \caption{Tiempo de Respuesta Promedio - 4 cores}
 \end{center}
 \end{table}
 
Una vez m\'as, el aumento del n\'umero de cores provee una gran reducci\'on del Tiempo de Respuesta, de hasta un 40\% con respecto a los experimentos con este algoritmo y solo 2 cores, y de hasta un 60\% con respecto a una ejecuci\'on de un solo core. Se aprecia, adem\'as, una mejor de casi el 30\% con respecto a simulaciones en las mismas condiciones con el algoritmo Round Robin original. \'Esto \'ultimo se debe a que al haber m\'as n\'ucleos, se generan m\'as migraciones entre estos n\'ucleos, y por ende, m\'as ciclos perdidos en dichas migraciones. Al prohibir las migraciones, como en los experimentos anteriores, este costo se reduce, pero como ventaja adicional, tener una mayor cantidad de cores permite que una mayor cantidad de procesos se asigne a cores diferentes, permitiendo que m\'as procesos encuentren disponible el core que les fue asignado y permanezcan m\'as tiempo corriendo en el mismo en lugar de quedar en estado Ready.

De manera similar al experimento con dos cores, al aumentar el quantum, la ventaja de este algoritmo que prohibe migraciones es menos significativa, ya que los procesos abandonan menos frecuentemente el CPU, y, consecuentemente, migran menos entre los cores disponibles.

Conclusiones:
\begin{description}
  \item[] \hfill \\
  Prohibir las migraciones entre n\'ucleos favorece el Tiempo de Respuesta mediante la mitigaci\'on de los costos de migraci\'on, los cuales pueden no ser demasiado flexibles para el scheduling de tareas. Mientras mayor sea el costo, m\'as eficiente ser\'a este algoritmo en t\'erminos de Tiempo de Respuesta.
  \item[] \hfill \\
    Sin embargo, esto trae como consecuencia que puede haber procesos listos para ejecutarse as\'i como procesadores ociosos y estos no puedan coordinarse para aumentar el throughput por la rigidez de este algoritmo.  
    \item[] \hfill \\
    Una vez m\'as, aumentar la cantidad de cores disponibles mejora ampliamente el Tiempo de Respuesta, a\'un m\'as que con nuestro algoritmo de Round Robin original. Idealmente, si se tiene tantos cores como procesos que se ejecutan a la vez, se obtendr\'ia un Tiempo de Respuesta a\'un mejor al evitar no solo las migraciones, sino tambi\'en los casos en los que un proceso espera a su propio CPU y evita ejecutarse en otro que est\'e disponible.
  \item[] \hfill \\
  El quantum debe ser breve. Mientras mayor es el quantum, es m\'as probable es que ocurra que un proceso bloquee el CPU necesitado por otro proceso y que este bloqueo dure una mayor cantidad de tiempo. Ya que se tiene una mayor flexibilidad eligiendo el quantum que en agregar m\'as n\'ucleos al sistema, si se prohiben migraciones, hay que asegurarse que el quantum sea peque\~no y se asigne suficiente tiempo para que la tarea avance en su ejecuci\'on. Un quantum de 10 ciclos proporciona un buen resultado para ambos algoritmos de Round Robin, otorgando un decremento del Waiting Time significativo y sin causar tantos ciclos perdidos esperando a un procesador en particular. Pero mientras m\'as alto es el quantum del algoritmo Round Robin que prohibe migraciones, m\'as se aproxima a su contraparte. Por lo tanto, quiz\'as ser\'ia mejor fijar el quantum de este nuevo algoritmo en un punto intermedio entre 5 y 10 ciclos para mejorar su Tiempo de Espera.


\end{description}


\subsection{M\'etrica: Turnaround}

Al igual que antes, realizaremos varias corridas por cada caso y calcularemos el Turnaround
 promedio ($TR_{prom}$) para ver como es el comportamiento 
del scheduler con respecto al scheduler anterior.. 

 $$TR_{prom}= \frac{\sum_{i=1}^{n}(TF_i - TE_i - TI_i)}{n}$$ 
\\Donde TF\_i es el tiempo en el que empieza el \'ultimo tramo de ejecuci\'on del 
proeces $i$, TE\_i es el tiempo de ejecuci\'on, TI\_i es el 
tiempo de llegada al scheduler del proceso $i$ y $n$ la cantidad de procesos.

A continuaci\'on realizaremos los mismo experimentos que en el ejercicio 7,
pero usando multi cores. Al igual que antes utilizaremos los mismo valores de quatums y 
cantidad de cpus.
%un solo core
\subsection{Caso 1: Dos cores y distintos quatums}


\underline{\bfseries 2 core y 5 quatum:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{m2_rr12core5qR1.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{m2_rr12core5qR2.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{m2_rr12core5qR3.png}

\underline{\bfseries 2 core y 10 quatum:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{m2_rr12core10qR1.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{m2_rr12core10qR2.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{m2_rr12core10qR3.png}


\underline{\bfseries 2 core y 20 quatum:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{m2_rr12core20qR1.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{m2_rr12core20qR2.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{m2_rr12core20qR3.png}
\\
Se puede ver que el tiempo total de ejecuci\'on varia es menor al del Round \- Robin, pasa a ser
de $140$ en comparaci\'on a los $200$ ciclos de reloj que utilizaba el otro algoritmo para ejecutar 
el mismo lote. El orden en el que se ejecutan las tareas es casi siempre la misma porque se
mantiene la cantidad de llamanadas bloqueantes apesar de que estas sean aleatorias, se procesan mas
r\'apido las que tienen pocas llamadas bloqueante. A continuaci\'on mostramos una tabla 
comparativa de los turnaround promedios con respecto a los diferentes quatums: 

 \begin{table}[!hbt]
\begin{center}
   \begin{tabular}{| c | c | c | c | }
	 
	 \hline
	\backslashbox{Nro Ejec}{Quantum}  & 5 & 10 & 20 \\ \hline
     1ra & 68.8 & 54.0 & 58.0 \\ \hline
     2da & 64.6 & 60.2 & 55.0 \\ \hline
     3ra & 84.0 & 66.2 & 56.4 \\ 
    \hline
   \end{tabular}
   \caption{Turnaround Promedio - 2 cores}
 \end{center}
 \end{table}


Si comparamos esta tabla con la tabla de Round Roubin vemos que el turnaround mejor sustancialemente.
El valor m\'inimo de turnaroun promedio para cuando el quatum era $5$ era de $127.0$ ciclos de clock y pas\'o
a ser de $64.6$ ciclos de clock, es una mejora del $50\%$ aproximadamente. De forma parecida sucede para
los otros valores de quatums, para el quatum $= \ 10$ hay una mejora del $16\%$ y para el quantum $= \ 20$
la mejora es del $10\%$.


\subsection{Caso 2: Distintos cores y quatums fijos} 
% varios cores
En este caso dejaremos fijo la cantidade de cores $= \ 2$, e iremos cambiando el quatum para ver 
en que cambia el turnaroun.

\underline{\bfseries 2 cores:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{m2_rr12core10qR1.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{m2_rr12core10qR2.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{m2_rr12core10qR3.png}
\\
\underline{\bfseries 4 cores:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{m2_rr14core10qR1.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{m2_rr14core10qR2.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{m2_rr14core10qR3.png}
\\

Podemos apreciar que el turnaround mejora a medida que la cantidad de cores aumenta.

\begin{center}
   \begin{tabular}{| c | c | c |}
     \hline
     \backslashbox{Nro Ejec}{Cant. Cores} & 2 cores & 4 cores\\ \hline
     1ra & 54.0 & 26.2\\ \hline
     2da & 66.2 & 26.8\\ \hline
     3ra & 66.2 & 27.4\\ 
     \hline
   \end{tabular}
 \end{center}

La mejora de $2$ a $4$ cores es del $52\%$ aproximadamente, en esto se parece mucho a
lo que pasaba en el experimento de Round Robin. En cuanto al orden de  finalizacion de
las tareas, \'estas se mantienen, pero se puede ver una gran mejora en los tiempos de respuesta. 
A continuaci\'on un tabla que indica el $turnaround$ de las tareas por cores.\\
\newpage

 \begin{table}[!hbt]
\begin{center}
   \begin{tabular}{| c | c | c | }
     \hline
     \backslashbox{Tarea}{Cant. Cores} & 2 & 4 \\ \hline
     0 &  23.0 & 13.0 \\ \hline
     1 &  25.0 & 12.0 \\ \hline
     2 &  88.0 & 31.0 \\ \hline
     3 &  24.0 & 2.0 \\ \hline
     4 & 110.0 & 73.0 \\ 
     \hline
   \end{tabular}
   \caption{Turnaround de tareas - 1era Ejec. - quatum 10}
 \end{center}
 \end{table}
 
  \begin{table}[!hbt]
\begin{center}
   \begin{tabular}{| c | c | c | }
     \hline
     \backslashbox{Tarea}{Cant. Cores} & 2 & 4 \\ \hline
     0 &  36.0 & 16.0 \\ \hline
     1 &  43.0 & 17.0 \\ \hline
     2 &  92.0 & 28.0 \\ \hline
     3 &  20.0 &  0.0 \\ \hline
     4 & 110.0 & 73.0 \\ 
     \hline
   \end{tabular}
      \caption{Turnaround de tareas - 2era Ejec. - quatum 10}
 \end{center}
 \end{table}
 
  \begin{table}[!hbt]
\begin{center}
   \begin{tabular}{| c | c | c | }
     \hline
     \backslashbox{Tarea}{Cant. Cores} & 2 & 4 \\ \hline
     0 &  44.0 & 15.0 \\ \hline
     1 &  50.0 & 14.0 \\ \hline
     2 &  88.0 & 29.0 \\ \hline
     3 &  37.0 &  6.0 \\ \hline
     4 & 112.0 & 73.0 \\ 
     \hline
   \end{tabular}
   \caption{Turnaround de tareas - 3era Ejec. - quatum 10}
 \end{center}
 \end{table}

 
Podemos notar que la disponibilidad de m\'as cores aumenta el tiempo de respuesta,
las mejoras son mas $70\%$ lo cual nos indica que este algoritmo en precesencia de m\'as cores
mejora el tiempo de respuesta de forma sustancial. En el caso del Round Robin existia una mejora
pero el porcentaje no era tan significante con estos nuevos resultados.\\

Trantando de reflejar este mismo comportamiento, probamos si mejoran los tiempos teniendo un 
mayor quatum. Para este caso aumentamos el quatum a $20$ ciclos de reloj y mantemos la misma 
variaci\'on de cores.


\underline{\bfseries 2 cores:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{m2_2core20qR1.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{m2_2core20qR2.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{m2_2core20qR3.png}
\\
\underline{\bfseries 4 cores:}
\\
\textbf{1ra ejec.}
\\
\includegraphics[width=150mm]{m2_4core20qR1.png}
\\
\textbf{2da ejec.}
\\
\includegraphics[width=150mm]{m2_4core20qR2.png}
\\
\textbf{3ra ejec.}
\\
\includegraphics[width=150mm]{m2_4core20qR3.png}
\\
Podemos ver que el tiempo total de ejecuci\'on no varia con respecto al experimento anterior $(quatum 10)$, si bien cada tarea mejora su tiempo de ejecuci\'on, esta variaci\'on es m\'inima dado que a pesar de tener mayor quatum las tareas bloqueantes impiden que se utilice en su totalidad por lo tanto no que da m\'as que esperar a que \'estas se desbloqueen. En la siguiente tabla vemos los tiempos de ejecuci\'on de cada tarea:

 \begin{table}[!hbt]
\begin{center}
   \begin{tabular}{| c | c | c | }
     \hline
     \backslashbox{Tarea}{Cant. Cores} & 2 & 4 \\ \hline
     0 &  39.0 &  9.0 \\ \hline
     1 &  64.0 & 30.0 \\ \hline
     2 &  89.0 & 55.0 \\ \hline
     3 &  30.0 & 15.0 \\ \hline
     4 & 110.0 & 72.0 \\ 
     \hline
   \end{tabular}
   \caption{Turnaround de tareas - 1ra Ejec. - quatum 20}
 \end{center}
 \end{table}
 
 \begin{table}[!hbt]
\begin{center}
   \begin{tabular}{| c | c | c | }
     \hline
     \backslashbox{Tarea}{Cant. Cores} & 2 & 4 \\ \hline
     0 &  35.0 & 12.0 \\ \hline
     1 &  65.0 & 25.0 \\ \hline
     2 &  84.0 & 58.0 \\ \hline
     3 &  23.0 &  0.0 \\ \hline
     4 & 110.0 & 73.0 \\ 
     \hline
   \end{tabular}
   \caption{Turnaround de tareas - 2da Ejec. - quatum 20}
 \end{center}
 \end{table}
 
 \begin{table}[!hbt]
\begin{center}
   \begin{tabular}{| c | c | c | }
     \hline
     \backslashbox{Tarea}{Cant. Cores} & 2 & 4 \\ \hline
     0 &  33.0 & 12.0 \\ \hline
     1 &  62.0 & 32.0 \\ \hline
     2 &  85.0 & 56.0 \\ \hline
     3 &  40.0 &  0.0 \\ \hline
     4 & 110.0 & 76.0 \\ 
     \hline
   \end{tabular}
   \caption{Turnaround de tareas - 3ra Ejec. - quatum 20}
 \end{center}
 \end{table}

Al igual que en el scheduler de Round Robin, aumentar el quatum
no influye demasiado el turnaround de las tareas. Si vemos los datos de la tabla de
''Turnaround de tareas \- 1ra Ejec. \- quatum 10'' y los del ''Turnaround de tareas \- 1ra Ejec. \- quatum 20''
 vemos que una mejora de $5$ ciclos de reloj aproximadamente por tarea. Por lo tanto aumentar 
el quantum no ayuda a mejorar el rendimiento en presencia de tareas que realizan 
muchas llamadas bloqueantes.
En resumen:

\begin{description}
	
  \item[] \hfill \\
  Al igual que en el Round Robin, en este algoritmo notamos que tener un quantum ''grande''
  , si bien mejora los tiempo, dicho porcentaje es bajo. Concluimos que se debe a que las tareas 
  tiene llamadas bloqueantes que no permiten el aprovechar la totalidad del quatum por lo tanto la
  mejora es minima. Tambien que turnaroun mejora con el uso de mas cpus.
  \item[] \hfill \\
   A diferencia del algoritmo de Round Robin, se puede observar que las tareas terminaban de ejecutarse
   mucho antes y que mejor\'o el tiempo total de ejecuci\'on. Tambien se vio una que el orden de
   finalizaci\'on de las tareas cambio respecto a este nuevo algoritmo, esto se ve reflejado en los
   tiempo de respuesta que mostramos en los experimentos anteriores
  \item[] \hfill \\
  Si elegimos un caso de gran notoriedad entre ambos schedulers, vemos que usando un 
  quanto ''chico'' la mejora de esta m\'etrica se ve reflejada en gran proporcion.(ver primer caso de prueba)
  \item[] \hfill \\
  Dado a los experimento vimos que era \'optimo elegir un quatum ''mediano'' con respecto al tiempo
  de ejecuci\'on de las tareas.En nuestro caso ser\'ia quantum $= \ 10$
  
\end{description}


\section{Ejercicio 9}

\input{Ejercicio9.txt}

\section{Conclusi\'on}

Existen varios algoritmos buenos de scheduling y cada uno tiene sus ventajas y desventajas, en este trabajo pr\'actico hemos podido ver 4 tipos de scheduler y sus distintos resultados dada las variantes de procesadores y tareas que se tengan en cuenta. Decidir que escheduler es mejor que otro dependera mucho de los tipos de procesos y recursos que este posea, y de los tiempos que utilice para el contex switch y el quatum (en el caso del Round Robin) dado que de estos dependera que su funcionamiento sea \'optimo.




\end{document}
